// Copyright  2004-2008 Backplane Ltd.
//
// This file is part of Ubiquity formsPlayer
//
// Ubiquity formsPlayer is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3 of the License, or (at your
// option) any later version.
//
// Ubiquity formsPlayer is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License
// along with Ubiquity formsPlayer If not, see <http://www.gnu.org/licenses/>.
//	
//
//   Purpose: implementation of CResolvedItem.
//   $Id$

#include "stdafx.h"
#include "resolvedItemList.h"
#include "resolveditem.h"

CResolvedItem::CResolvedItem(CResolvedItemList * pOwnerList)
	:m_sLabel("")
	,m_bIsCurrentlySelected(false)
	,m_pList(pOwnerList)
{
	//If the variant is left completely uninitialised,
	//	There is a chance that vt might be VT_DISPATCH
	//	This would cause a crash.
	m_vtVal.vt = VT_EMPTY;
}

CResolvedItem::~CResolvedItem(void)
{
	emptyCurrentValue();
}

// stores a string as the resolved value for this item
HRESULT CResolvedItem::put_value(BSTR sValue)
{
	HRESULT hr = S_OK;
	emptyCurrentValue();
	m_vtVal.vt = VT_BSTR;
	m_vtVal.bstrVal = sValue;
	return hr;
}

// stores a node as the resolved value for this item
HRESULT CResolvedItem::put_value(IXMLDOMNode * pNode)
{
	HRESULT hr = S_OK;
	emptyCurrentValue();
	m_vtVal.pdispVal = pNode;
	m_vtVal.vt = VT_DISPATCH;
	pNode->AddRef();
	return hr;
}

// stores a ResolvedItemlist as the resollved value for this item,
//	ie. this is bound to choices
HRESULT CResolvedItem::put_value(CResolvedItemList* pList)
{
	HRESULT hr = S_OK;
	emptyCurrentValue();
	m_vtVal.vt = VT_I4;
	m_vtVal.lVal = reinterpret_cast<long>(pList);
	return hr;
}

// called by the put_value functions to properly 
//	clear the current value and free any associated memory.
void CResolvedItem::emptyCurrentValue(void)
{
	switch(m_vtVal.vt)
	{
		case VT_DISPATCH:
			//Release the node pointer
			::safeRelease(m_vtVal.pdispVal);
			break;
		case VT_I4:
			//do nothing, we don't own the memory to which this points
			m_vtVal.lVal = 0;
			break;
		case VT_BSTR:
			//I don't know whether to do nothing or call
			//	SysFreeString, I will need to examine closer 
			//	whether this object owns the string or not.
			//The safest move is to do nothing, as that will
			//	only cause an internal buildup of memory usage
			//	if I am wrong.  Freeing it could cause unpredictable
			//	behaviour if this object does not own the string.
			break;
	}
}

// retrieves a copy of the underlying resolved value.
HRESULT CResolvedItem::get_value(VARIANT * pvtRetVal)
{
	HRESULT hr = S_FALSE;
	if(VT_EMPTY != m_vtVal.vt)
	{
		hr = S_OK;
		CComVariant vt;
		vt.Copy(&m_vtVal);
		*pvtRetVal = vt;
	}
	return hr;
}


HRESULT CResolvedItem::put_label(BSTR s)
{
	//TODO: notify whatever is interested.
	HRESULT hr = S_OK;
	m_sLabel = s;
	return hr;
}

HRESULT CResolvedItem::select(bool bFireEvent)
{
	HRESULT hr = S_FALSE;
	//Don't bother to do anything if attempting
	//	to set the value to the current value.
	if(!m_bIsCurrentlySelected)
	{
		if(bFireEvent)
		{
			//fire the event on the corresponding.
			//	real item (if any)
		}
		m_pList->SelectItem(this);
		m_bIsCurrentlySelected = true;
	}
	return hr;
}

HRESULT CResolvedItem::deselect(bool bFireEvent)
{
	HRESULT hr = S_FALSE;
	//Don't bother to do anything if attempting
	//	to set the value to the current value.
	if(m_bIsCurrentlySelected)
	{
		if(bFireEvent)
		{
			//fire the event on the corresponding.
			//	real item (if any)
		}
		m_pList->DeselectItem(this);
		m_bIsCurrentlySelected = false;
	}
	return hr;
}